package com.sxbbc.common.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.function.common.GetRest;
import com.function.common.RestResponse;
import com.sxbbc.common.basics.enums.RandNumType;
import com.sxbbc.common.basics.exceptions.ThrowJsonException;
import com.sxbbc.common.basics.files.RestUploadFileInfo;
import com.sxbbc.common.basics.service.config.Config;
import com.sxbbc.common.basics.utils.calculation.CalcuUtils;
import com.sxbbc.common.basics.utils.dto.Properties;
import com.sxbbc.common.basics.utils.encrypts.des.DESEncode;
import com.sxbbc.common.basics.utils.radoms.RandNumUtils;
import com.sxbbc.common.basics.utils.statics.StaticUtils;
import com.sxbbc.common.core.entity.jz.*;
import com.sxbbc.common.core.enums.*;
import com.sxbbc.common.core.mapper.jz.BBusinessMapper;
import com.sxbbc.common.core.mapper.jz.CCustomerMapper;
import com.sxbbc.common.core.service.*;
import com.sxbbc.common.core.utils.BasePage;
import com.sxbbc.common.core.utils.FileUtils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 店铺信息表 服务实现类
 * </p>
 *
 * @author leehao
 * @since 2019-05-08
 */
@Service
public class BBusinessServiceImpl extends ServiceImpl<BBusinessMapper, BBusiness> implements BBusinessService {

    @Autowired
    private IAddressService addressService;
    @Autowired
    private IBLoginService bLoginService;
    @Autowired
    private CCustomerMapper customerMapper;
    @Autowired
    private IBAccountService bAccountService;
    @Autowired
    private IInfoParamService infoParamService;
    @Autowired
    private IIndustryService iIndustryService;

    @Override
    public Page<BBusiness> queryBusinessList(BasePage<BBusiness> page, BBusiness business) {
        QueryWrapper<BBusiness> wrapper = queryWrapper(business);
        if (page.isPaging()) {
            super.page(page, wrapper);
        } else {
            List<BBusiness> list = super.list(wrapper);
            page.setRecords(list);
        }
        CalcuUtils calUtil = CalcuUtils.getInstance();
        for (BBusiness b : page.getRecords()) {
            b.setBusinessTypeName(BusinessTypeEnums.getName(b.getBType()));
            b.setFromName(FromTypeEnums.getName(b.getFromType()));
            //是否能够查看商品列表 线上或全部 且审核通过
//            if (calUtil.isEquals(b.getOnOff(), BusinessScopeEnums.ONLINE.getId())) {
            if (calUtil.isEquals(b.getStatus(), StaticUtils.STATUS_SUCCESS)
                    || calUtil.isEquals(b.getOfflineStatus(), StaticUtils.STATUS_SUCCESS)) {
                b.setLookProduct(true);
            }
//            }

            if (calUtil.isEquals(b.getOnOff(), BusinessScopeEnums.ONLINE.getId())) {

            }
            Industry industry = iIndustryService.getById(b.getIndustryId());
            if (industry != null) {
                b.setIndustryName(industry.getName());
            }
        }
        return page;
    }

    @Override
    public RestResponse addBusiness(BBusiness business) {
        CalcuUtils calUtil = CalcuUtils.getInstance();
        CCustomer customer = new CCustomer();
        boolean save = false;
        //新增时 获取到申请的类型 线上、线下
        if (calUtil.isEquals(business.getFromType(), FromTypeEnums.PLAT_ADD.getId())) {
            //平台新增 验证绑定的用户是否存在
            customer = customerMapper.getCustomerByPhone(business.getExistPhone());
            if (customer == null) {
                return GetRest.getFail("绑定的用户不存在！");
            }
            BBusiness bBusiness = selectByCid(customer.getId());
            if (bBusiness != null) {
                return GetRest.getFail("该用户已申请，请勿重新申请");
            }
            business.setCid(customer.getId());
            //获取经纬度 线下
            if (calUtil.isEquals(business.getOnOff(), BusinessScopeEnums.OFFLINE.getId())) {
                Properties properties = Config.properties;
                String addrName = addressService.getAddrName(business.getProId(), business.getCityId(), business.getAreaId());
                Map<String, String> location = calUtil.getLatAndLonByAmap(properties.getAmapKey(), addrName + " " + business.getAddressDetail());
                if (!CollectionUtils.isEmpty(location)) {
                    String lat = location.get("lat");
                    String lon = location.get("lon");
                    business.setLatVal(lat);
                    business.setLonVal(lon);
                } else {
                    return GetRest.getFail("无法设置经纬度，请检查地址是否正确");
                }
                business.setOfflineStatus(StaticUtils.STATUS_SUCCESS);
            } else {
                business.setStatus(StaticUtils.STATUS_SUCCESS);
            }
            save = super.save(business);
            if (!save) {
                throw new ThrowJsonException("保存商家资料失败");
            }
            //进入账号、账户新增，分佣比例设置
            return handleApplySuccessAddBLogin(business);
        } else {
            return GetRest.getFail("商家来源参数异常");
        }
    }

    @Override
    public RestResponse addBusinessForApi(BBusiness business) {
        CalcuUtils calUtil = CalcuUtils.getInstance();
        Properties properties = Config.properties;
        boolean save = false;
        if (calUtil.isEquals(business.getFromType(), FromTypeEnums.SELF_SETTLED.getId())) {
            CCustomer customer = customerMapper.selectById(business.getCid());
            BBusiness bBusiness = selectByCid(customer.getId());
            if (bBusiness != null) {
                //个人商家
                boolean personalStatus = !calUtil.isEquals(bBusiness.getStatus(), StaticUtils.STATUS_SUCCESS)
                        || !calUtil.isEquals(bBusiness.getOfflineStatus(), StaticUtils.STATUS_SUCCESS);
                if (personalStatus) {
                    //数据转换
                    business.setId(bBusiness.getId());
                    business.setCid(bBusiness.getCid());
                    business.setQrUrl(bBusiness.getQrUrl());
                    business.setCreatetime(bBusiness.getCreatetime());
                    business.setScale(bBusiness.getScale());

                    if (calUtil.isEquals(business.getOnOff(), BusinessScopeEnums.OFFLINE.getId())) {
                        if (StringUtils.isNotBlank(business.getAddressDetail())) {
                            //第一次被驳回 更改了地址信息 更新经纬度
                            String addrName = addressService.getAddrName(business.getProId(),
                                    business.getCityId(), business.getAreaId());
                            Map<String, String> location = calUtil.getLatAndLonByAmap(properties.getAmapKey(),
                                    addrName + " " + business.getAddressDetail());
                            if (!CollectionUtils.isEmpty(location)) {
                                String lat = location.get("lat");
                                String lon = location.get("lon");
                                business.setLatVal(lat);
                                business.setLonVal(lon);
                            }
                        }
                    }
                    save = super.updateById(business);
                    if (!save) {
                        throw new ThrowJsonException("保存商家资料失败");
                    }
                    return GetRest.getSuccess("保存成功", business.getId());
                }
                return GetRest.getFail("该用户已申请，请勿重复操作");
            } else {
                if (calUtil.isEquals(business.getOnOff(), BusinessScopeEnums.OFFLINE.getId())) {
                    if (StringUtils.isNotBlank(business.getAddressDetail())) {
                        //第一次被驳回 更改了地址信息 更新经纬度
                        String addrName = addressService.getAddrName(business.getProId(),
                                business.getCityId(), business.getAreaId());
                        Map<String, String> location = calUtil.getLatAndLonByAmap(properties.getAmapKey(),
                                addrName + " " + business.getAddressDetail());
                        if (!CollectionUtils.isEmpty(location)) {
                            String lat = location.get("lat");
                            String lon = location.get("lon");
                            business.setLatVal(lat);
                            business.setLonVal(lon);
                        }
                    }
                }
                business.setCid(customer.getId());
                save = super.save(business);
                if (!save) {
                    throw new ThrowJsonException("保存商家资料失败");
                }
                return GetRest.getSuccess("保存成功", business.getId());
            }
        } else {
            return GetRest.getFail("申请来源异常");
        }
    }

    @Override
    public RestResponse handleResetBusinessPassword(Integer id, Integer type) {
        DESEncode des = DESEncode.getInstance();
        boolean save = false;
        switch (type) {
            case 1:
                // 重置登录密码
                QueryWrapper<BLogin> wrapper = new QueryWrapper<>();
                wrapper.eq("bid", id);
                BLogin blogin = bLoginService.getOne(wrapper);
                blogin.setPassWord(des.encrypt(StaticUtils.DEFAULT_PASSWORD));
                save = bLoginService.updateById(blogin);
                break;
            case 2:
                // 重置交易密码
                BBusiness business = super.getById(id);
                business.setPayWord(des.encrypt(StaticUtils.DEFAULT_PASSWORD));
                save = super.updateById(business);
                break;
            default:
                break;
        }
        if (!save) {
            throw new ThrowJsonException("重置商家密码失败");
        }
        return GetRest.getSuccess("重置密码成功");
    }

    @Override
    public RestResponse handleApplySuccessAddBLogin(BBusiness business) {
        CalcuUtils calUtil = CalcuUtils.getInstance();
        boolean save = false;
        //登录对象建立
        BLogin login = new BLogin();
        if (calUtil.isEquals(business.getFromType(), FromTypeEnums.PLAT_ADD.getId())) {
            login.setLogin(business.getExistPhone());
            if (StringUtils.isNotBlank(business.getCompanyName())) {
                login.setNickName(business.getCompanyName());
            } else {
                login.setNickName(business.getNickName());
            }
            login.setPhone(business.getLinkPhone());
        } else if (calUtil.isEquals(business.getFromType(), FromTypeEnums.SELF_SETTLED.getId())) {
            CCustomer customer = customerMapper.selectById(business.getCid());
            if (customer != null) {
                login.setLogin(customer.getPhone());
            }
            if (StringUtils.isNotBlank(business.getCompanyName())) {
                login.setNickName(business.getCompanyName());
            } else {
                login.setNickName(business.getNickName());
            }
            login.setPhone(business.getLinkPhone());
        }
        if (StringUtils.isNotBlank(business.getNickName())) {
            login.setRealName(business.getRealName());
        }
        login.setBid(business.getId());
        // 密码加密
        login.setPassWord(DESEncode.getInstance().encrypt(StaticUtils.DEFAULT_PASSWORD));
        login.setCreatetime(new Date());
        login.setIsPrimaryLogin(StaticUtils.STATUS_YES);
        login.setStatus(StaticUtils.STATUS_YES);
        //TODO 待优化
        if (calUtil.isEquals(business.getBType(), BusinessTypeEnums.OWN_BUSINESS.getId()) &&
                (calUtil.isEquals(business.getOnOff(), BusinessScopeEnums.OFFLINE.getId()))) {
            login.setRoleId(StaticUtils.BUSINESS_ROLE_2); //自营线下商家（包含养鸡模块）
        } else {
            login.setRoleId(StaticUtils.BUSINESS_ROLE_1);//入驻线下商家（不包含养鸡模块）
        }
        save = bLoginService.save(login);
        if (!save) {
            throw new ThrowJsonException("[平台新增商家]商家账号创建失败");
        }
        //商家账户建立
        BAccount bAccount = bAccountService.selectByBid(business.getId());
        if (bAccount == null) {
            bAccount = new BAccount();
            bAccount.setBid(business.getId());
            save = bAccountService.save(bAccount);
            if (!save) {
                throw new ThrowJsonException("建立商家账户失败");
            }
        }
        //设置商家编码并更新
        RandNumUtils rand = RandNumUtils.getInstance();
        String businessCode = rand.get(RandNumType.NUMBER_LETTER, 5).toUpperCase();
        BBusiness queryBusiness = selectByBusinessCode(businessCode);
        if (queryBusiness == null) {
            business.setBusinessCode(businessCode);
        } else {
            business.setBusinessCode(rand.get(RandNumType.NUMBER_LETTER, 5).toUpperCase());
        }
        //针对个人商家设置
        BBusiness oldBusiness = super.getById(business.getId());
        if (StringUtils.isBlank(oldBusiness.getQrUrl())) {
            RestUploadFileInfo r = FileUtils.getQRCodeBusinessPay(business.getId());
            business.setQrUrl(r.getData());
        }
        if (calUtil.isEquals(business.getOnOff(), BusinessScopeEnums.OFFLINE.getId()) && business.getScale() == null) {
            //商家分佣比例设置
            BigDecimal businessScale = calUtil.getValueByClass(BigDecimal.class, infoParamService.getValueByCode(ParamEnums.BUSINESS_SCALE));
            business.setScale(businessScale);
        }
        save = super.updateById(business);
        if (!save) {
            throw new ThrowJsonException("设置商家编码失败");
        }
        return GetRest.getSuccess("保存成功", business.getBusinessCode());
    }

    @Override
    public BBusiness selectByBusinessCode(String businessCode) {
        QueryWrapper<BBusiness> wrapper = new QueryWrapper<>();
        wrapper.eq("business_code", businessCode);
        return super.getOne(wrapper);
    }

    @Override
    public RestResponse editBusiness(BBusiness business) {
        CalcuUtils calUtil = CalcuUtils.getInstance();
        //获取到原来的商家对象
        BBusiness editBusiness = super.getById(business.getId());
        if (editBusiness == null) {
            return GetRest.getFail("该商家不存在！");
        }
        if (calUtil.isEquals(business.getOnOff(), BusinessScopeEnums.OFFLINE.getId())) {
            //商家付款码
            RestUploadFileInfo r = FileUtils.getQRCodeBusinessPay(business.getId());
            business.setQrUrl(r.getData());
        }
        //经纬度更新
        if (StringUtils.isNotBlank(business.getLonlat())) {
            String lonlat = business.getLonlat();
            lonlat.replace(" ", "");
            String[] arr = lonlat.split(",");
            if (!"0,0".equals(lonlat) && arr.length > 1) {
                business.setLonVal(arr[0]);
                business.setLatVal(arr[1]);
            }
        } else {
            Properties properties = Config.properties;
            String addrName = addressService.getAddrName(business.getProId(), business.getCityId(), business.getAreaId());
            Map<String, String> location = calUtil.getLatAndLonByAmap(properties.getAmapKey(), addrName + " " + business.getAddressDetail());
            if (!CollectionUtils.isEmpty(location)) {
                String lat = location.get("lat");
                String lon = location.get("lon");
                business.setLatVal(lat);
                business.setLonVal(lon);
            }
        }
        //保存商家
        Integer count = super.baseMapper.updateBusinessForApi(business);
        if (count < 1) {
            throw new ThrowJsonException("保存商家资料失败");
        }
        return GetRest.getSuccess("保存成功！");
    }

    @Override
    public RestResponse editBusinessForApi(BBusiness business) {
        CalcuUtils calUtil = CalcuUtils.getInstance();
        //获取到原来的申请商家对象
        BBusiness editBusiness = super.getById(business.getId());
        if (editBusiness == null) {
            return GetRest.getFail("该申请入驻记录不存在！");
        }
        //线下地址获取经纬度
        if (calUtil.isEquals(business.getOnOff(), BusinessScopeEnums.OFFLINE.getId())) {
            Properties properties = Config.properties;
            if (StringUtils.isNotBlank(business.getAddressDetail())) {
                //第一次被驳回 更改了地址信息 更新经纬度
                String addrName = addressService.getAddrName(business.getProId(),
                        business.getCityId(), business.getAreaId());
                Map<String, String> location = calUtil.getLatAndLonByAmap(properties.getAmapKey(),
                        addrName + " " + business.getAddressDetail());
                if (!CollectionUtils.isEmpty(location)) {
                    String lat = location.get("lat");
                    String lon = location.get("lon");
                    business.setLatVal(lat);
                    business.setLonVal(lon);
                }
            }
        }
        Integer updateFlag = baseMapper.updateBusinessForApi(business);
        if (updateFlag < 1) {
            throw new ThrowJsonException("保存商家资料失败");
        }
        return GetRest.getSuccess("保存成功");
    }

    /**
     * 通过cid查询到商家对象
     *
     * @param cid 用户ID
     * @return com.sxbbc.common.core.entity.jz.BBusiness
     * @author leehao
     */
    private BBusiness selectByCid(Integer cid) {
        QueryWrapper<BBusiness> wrapper = new QueryWrapper<>();
        wrapper.eq("cid", cid);
        return super.getOne(wrapper);
    }

    /**
     * 公用查询条件
     *
     * @author leehao
     */
    @SuppressWarnings("unchecked")
    private QueryWrapper<BBusiness> queryWrapper(BBusiness business) {
        QueryWrapper<BBusiness> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(business.getNickName())) {
            wrapper.like("nick_name", business.getNickName()).
                    or().like("nick_name_on", business.getNickName());
        }
        if (StringUtils.isNotBlank(business.getQueryTime())) {
            String[] times = business.getQueryTime().split("~");
            wrapper.apply(true, "date_format(createtime,'%Y-%m-%d') >= {0}", times[0].trim());
            wrapper.apply(true, "date_format(createtime,'%Y-%m-%d') <= {0}", times[1].trim());
        }
        if (StringUtils.isNotBlank(business.getLicenseCode())) {
            wrapper.eq("license_code", business.getLicenseCode());
        }
        if (StringUtils.isNotBlank(business.getPhone())) {
            wrapper.eq("phone", business.getPhone());
        }
        if (StringUtils.isNotBlank(business.getBusinessCode())) {
            wrapper.eq("business_code", business.getBusinessCode());
        }
        if (business.getStatus() != null) {
            wrapper.eq("status", business.getStatus()).
                    or().eq("offline_status", business.getStatus());
        }
        if (business.getProId() != null) {
            wrapper.eq("pro_id", business.getProId());
        }
        if (business.getCityId() != null) {
            wrapper.eq("city_id", business.getCityId());
        }
        if (business.getAreaId() != null) {
            wrapper.eq("area_id", business.getAreaId());
        }
        return wrapper;
    }
}